home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’95 / Menu Controls / ShapeCommands.cp < prev    next >
Text File  |  1995-06-24  |  49KB  |  1,571 lines

  1. // Copyright © 1994-95 by Apple Computer, Inc. All rights reserved.
  2. // ShapeCommands.cp
  3.  
  4. #ifndef __SHAPECOMMANDS__
  5. #include "ShapeCommands.h"
  6. #endif
  7.  
  8. // MacApp
  9.  
  10. #ifndef __UFAILURE__
  11. #include <UFailure.h>
  12. #endif
  13.  
  14. #ifndef __UCLIPBOARDMGR__
  15. #include <UClipboardMgr.h>
  16. #endif
  17.  
  18. #ifndef __UMEMORY__
  19. #include <UMemory.h>
  20. #endif
  21.  
  22. #ifndef __UWINDOW__
  23. #include <UWindow.h>
  24. #endif
  25.  
  26. #ifndef __UMACAPPUTILITIES__
  27. #include <UMacAppUtilities.h>
  28. #endif
  29.  
  30. // DrawShapes
  31.  
  32. #ifndef __PATTERNMENU__
  33. #include "PatternMenu.h"
  34. #endif
  35.  
  36. #ifndef __UDRAWSHAPES__
  37. #include "UDrawShapes.h"
  38. #endif
  39.  
  40. #ifndef __UPICTSHAPE__
  41. #include "UPictShape.h"
  42. #endif
  43.  
  44. #ifndef __USHAPESDOCUMENT__
  45. #include "UShapesDocument.h"
  46. #endif
  47.  
  48. #ifndef __USHAPEVIEW__
  49. #include "UShapeView.h"
  50. #endif
  51.  
  52. #ifndef __UTEXTSHAPE__
  53. #include "UTextShape.h"
  54. #endif
  55.  
  56. //--------------------------------------------------------------------------------------------------
  57. // More Constants
  58.  
  59. // Minimum height and width of new shapes
  60. #define kMinHeight 20
  61. #define kMinWidth  20
  62.  
  63. CPoint            gClipMargin(16,16);                // the top & left margins to use when
  64.                                                 // displaying shapes in the Clipboard
  65.  
  66. //========================================================================================
  67. // Functions and structs used by EachVirtualShapeDo and EachNewShapeDo
  68. // typedef void(* DoToShapeType)(TShape* item, void* staticLink);
  69.  
  70. //----------------------------------------------------------------------------------------
  71. #pragma segment ADoCommand
  72.  
  73. void BeInvalidated(TShape* shape, void* staticLink)
  74. {
  75.     // staticLink is really a TShapeView*
  76.     TShapeView* shapeView = (TShapeView*)staticLink;
  77.  
  78.     shapeView->InvalShape(shape);
  79. }
  80.  
  81. //----------------------------------------------------------------------------------------
  82. #pragma segment ADoCommand
  83.  
  84. void BeSelected(TShape* shape, void* staticLink)
  85. {
  86.     // staticLink is really a TShapeView*
  87.     TShapeView* shapeView = (TShapeView*)staticLink;
  88.  
  89.     shape->SetSelected(true);
  90.     shapeView->InvalShape(shape);
  91. }
  92.  
  93. //----------------------------------------------------------------------------------------
  94. #pragma segment ADoCommand
  95.  
  96. void EraseShape(TShape* shape, void* staticLink)
  97. {
  98.     // staticLink is really a TShapeView*
  99.     TShapeView* shapeView = (TShapeView*)staticLink;
  100.  
  101.     if (shape->IsSelected())
  102.         shapeView->InvalShape(shape);
  103. }
  104.  
  105. //----------------------------------------------------------------------------------------
  106. #pragma segment ADoCommand
  107.  
  108. void HandleIt(TShape* shape, void* staticLink)
  109. {
  110.     // staticLink is really a TShapeDocument*
  111.     TShapeDocument* shapeDocument = (TShapeDocument*)staticLink;
  112.  
  113.     if (shape->WasSelected())
  114.         shapeDocument->DeleteShape(shape);
  115. }
  116.  
  117. //----------------------------------------------------------------------------------------
  118. struct HighlightRec
  119. {
  120.     CRect&        fBounds;
  121.     TShapeView*    fShapeView;
  122.  
  123.     HighlightRec(CRect& bounds, TShapeView* shapeView);
  124. };
  125.  
  126. #pragma segment ADoCommand
  127.  
  128. HighlightRec::HighlightRec(CRect& bounds, TShapeView* shapeView) :
  129.     fBounds(bounds),
  130.     fShapeView(shapeView)
  131. {
  132. }
  133.  
  134. //----------------------------------------------------------------------------------------
  135. #pragma segment ADoCommand
  136.  
  137. void HighlightShape(TShape* shape, void* staticLink)
  138. {
  139.     // staticLink is really a HighlightRec*
  140.     HighlightRec* hlRecPtr = (HighlightRec*)staticLink;
  141.  
  142.     CRect extent;
  143.     shape->GetFrame(extent);
  144.     if (RectsNest(hlRecPtr->fBounds, extent))
  145.     {
  146.         if (shape->IsSelected())
  147.             shape->Highlight(hlOn, hlOff, hlRecPtr->fShapeView);
  148.         else
  149.             shape->Highlight(hlOff, hlOn, hlRecPtr->fShapeView);
  150.         shape->SetSelected(!shape->IsSelected());
  151.     }
  152. }
  153.  
  154. //========================================================================================
  155. // CLASS TShapeCommand
  156. //========================================================================================
  157. #undef Inherited
  158. #define Inherited TBetterFeedbackCmd
  159.  
  160. #pragma segment ASelCommand
  161. MA_DEFINE_CLASS_M1(TShapeCommand, Inherited);
  162.  
  163. //----------------------------------------------------------------------------------------
  164. // TShapeCommand Constructor
  165. //----------------------------------------------------------------------------------------
  166. #pragma segment ASelCommand
  167.  
  168. TShapeCommand::TShapeCommand()
  169. {
  170.     fShapeView = NULL;
  171.     fShapeDocument = NULL;
  172. }
  173.  
  174. //----------------------------------------------------------------------------------------
  175. // TShapeCommand::IShapeCommand
  176. //----------------------------------------------------------------------------------------
  177. #pragma segment ASelCommand
  178.  
  179. void TShapeCommand::IShapeCommand(CommandNumber itsCommandNumber,
  180.                                   TShapeView* itsShapeView,
  181.                                   Boolean canUndo,
  182.                                   Boolean causesChange,
  183.                                   const VPoint& theMouse,
  184.                                   Boolean betterFeedbackDesired)
  185. {
  186.     this->IBetterFeedbackCmd(itsCommandNumber,
  187.                              itsShapeView->fShapeDocument,
  188.                              canUndo, 
  189.                              causesChange,
  190.                              itsShapeView->fShapeDocument,
  191.                              itsShapeView,
  192.                              itsShapeView->GetScroller(FALSE),
  193.                              theMouse,
  194.                              betterFeedbackDesired);
  195.     fShapeView = itsShapeView;
  196.     fShapeDocument = itsShapeView->fShapeDocument;
  197. }
  198.  
  199. //========================================================================================
  200. // CLASS TShapeSelector
  201. //========================================================================================
  202. #undef Inherited
  203. #define Inherited TShapeCommand
  204.  
  205. #pragma segment ASelCommand
  206. MA_DEFINE_CLASS_M1(TShapeSelector, Inherited);
  207.  
  208. //----------------------------------------------------------------------------------------
  209. // TShapeSelector Constructor
  210. //----------------------------------------------------------------------------------------
  211. #pragma segment ASelCommand
  212.  
  213. TShapeSelector::TShapeSelector()
  214. {
  215.     fLastMarch = 0;
  216.     fBounds = gZeroRect;
  217.     fShiftKey = false;
  218. }
  219.  
  220. //----------------------------------------------------------------------------------------
  221. // TShapeSelector::IShapeSelector
  222. //----------------------------------------------------------------------------------------
  223. #pragma segment ASelCommand
  224.  
  225. void TShapeSelector::IShapeSelector(CommandNumber itsCommandNumber,
  226.                                     TShapeView* itsShapeView,
  227.                                     const VPoint& theMouse)
  228. {
  229.     this->IShapeCommand(itsCommandNumber,
  230.                         itsShapeView,
  231.                         kCantUndo,
  232.                         kDoesNotCauseChange,
  233.                         theMouse,
  234.                         gBetterFeedback);
  235.     CStr255 hexString = "7C3E1F8FC7E3F1F8";
  236.     StuffHex(&fAnts, hexString);
  237. }
  238.  
  239. //----------------------------------------------------------------------------------------
  240. // TShapeSelector::DoIt
  241. //----------------------------------------------------------------------------------------
  242. #pragma segment ADoCommand
  243.  
  244. void TShapeSelector::DoIt()    // Override
  245. {
  246.     HighlightRec hlRec(fBounds, fShapeView);
  247.     fShapeDocument->EachVirtualShapeDo(&HighlightShape, (void*)&hlRec);
  248. }
  249.  
  250. //----------------------------------------------------------------------------------------
  251. // TShapeSelector::TrackFeedback
  252. //----------------------------------------------------------------------------------------
  253. #pragma segment ADoCommand
  254.  
  255. void TShapeSelector::TrackFeedback(TrackPhase aTrackPhase,
  256.                                    const VPoint& anchorPoint,
  257.                                    const VPoint& previousPoint,
  258.                                    const VPoint& nextPoint,
  259.                                    Boolean mouseDidMove,
  260.                                    Boolean turnItOn)    // Override
  261. {
  262.     Inherited::TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint,
  263.                              mouseDidMove, turnItOn);
  264.     CRect r;
  265.     Pt2Rect(fView->ViewToQDPt(anchorPoint), fView->ViewToQDPt(nextPoint), r);
  266.  
  267.     switch (aTrackPhase)
  268.     {
  269.         case trackBegin:
  270.         case trackEnd:
  271.             PenPat(&fAnts);
  272.             FrameRect(r);                // draw/Erase
  273.             break;
  274.  
  275.         case trackContinue:
  276.             if (turnItOn)
  277.             {
  278.                 if (mouseDidMove)
  279.                 {
  280.                 PenPat(&fAnts);
  281.                 FrameRect(r);
  282.                 }
  283.                 else if (TickCount() - fLastMarch >= 4)
  284.                 {
  285.                     Pattern oldPat = fAnts;
  286.                     RotatePat(fAnts);
  287.                     Pattern diffPat;
  288.                     XorPat(oldPat, fAnts, diffPat);
  289.                     PenPat(&diffPat);
  290.                     FrameRect(r);        // march
  291.                     fLastMarch = TickCount();
  292.                 }
  293.             }
  294.             else
  295.             {
  296.                 if (mouseDidMove)
  297.                 {
  298.                     PenPat(&fAnts);
  299.                     FrameRect(r);        // erase
  300.                 }
  301.             }
  302.             break;
  303.     }
  304. }
  305.  
  306. //----------------------------------------------------------------------------------------
  307. // TShapeSelector::TrackMouse
  308. //----------------------------------------------------------------------------------------
  309. #pragma segment ADoCommand
  310.  
  311. TTracker* TShapeSelector::TrackMouse(TrackPhase aTrackPhase,
  312.                                      VPoint& anchorPoint,
  313.                                      VPoint& previousPoint,
  314.                                      VPoint& nextPoint,
  315.                                      Boolean mouseDidMove)    // Override
  316. {
  317.     TTracker* newTracker = Inherited::TrackMouse(aTrackPhase, anchorPoint, previousPoint,
  318.                                                  nextPoint, mouseDidMove);
  319.  
  320.     CRect r;
  321.     CPoint qdAnchor = fShapeView->ViewToQDPt(anchorPoint);
  322.     CPoint qdPrevious = fShapeView->ViewToQDPt(previousPoint);
  323.     Pt2Rect(qdAnchor, qdPrevious, r);
  324.     fBounds = r;
  325.  
  326.     return newTracker;
  327. }
  328.  
  329. //========================================================================================
  330. // CLASS TShapeDragger
  331. //========================================================================================
  332. #undef Inherited
  333. #define Inherited TShapeCommand
  334.  
  335. #pragma segment ASelCommand
  336. MA_DEFINE_CLASS_M1(TShapeDragger, Inherited);
  337.  
  338. //----------------------------------------------------------------------------------------
  339. // TShapeDragger Constructor
  340. //----------------------------------------------------------------------------------------
  341. #pragma segment ASelCommand
  342.  
  343. TShapeDragger::TShapeDragger()
  344. {
  345.     fBounds = gZeroRect;
  346.     fDeltaH = 0;
  347.     fDeltaV = 0;
  348. }
  349.  
  350. //----------------------------------------------------------------------------------------
  351. // TShapeDragger::IShapeDragger
  352. //----------------------------------------------------------------------------------------
  353. #pragma segment ASelCommand
  354.  
  355. void TShapeDragger::IShapeDragger(TShapeView* itsShapeView,
  356.                                   const VPoint& theMouse)
  357. {
  358.     this->IShapeCommand(cMoveShape, itsShapeView, kCanUndo, kCausesChange,
  359.                         theMouse, gBetterFeedback);
  360.  
  361.     CRect bounds;
  362.     short numberOfShapes;
  363.     fShapeDocument->SurveyShapes(true, numberOfShapes, bounds);
  364.     itsShapeView->SetDragging(false);
  365.     fBounds = bounds;
  366.     fConstrainsMouse = gConstrainDrags;
  367. }
  368.  
  369. //----------------------------------------------------------------------------------------
  370. // TShapeDragger::DoIt
  371. //----------------------------------------------------------------------------------------
  372. #pragma segment ADoCommand
  373.  
  374. void TShapeDragger::DoIt()    // Override
  375. {
  376.     this->MoveBy(fDeltaH, fDeltaV);
  377. }
  378.  
  379. //----------------------------------------------------------------------------------------
  380. // TShapeDragger::MoveBy
  381. //----------------------------------------------------------------------------------------
  382. #pragma segment ADoCommand
  383.  
  384. void TShapeDragger::MoveBy(long deltaH, long deltaV)
  385. {
  386.     fShapeView->Focus();
  387.  
  388.     CShapeIterator iter(fShapeDocument->GetShapeList());
  389.     for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  390.     {
  391.         if (shape->IsSelected())
  392.         {
  393.             CRect extent;
  394.             shape->GetFrame(extent);
  395.             OffsetRect(extent, (short)deltaH, (short)deltaV);
  396.             shape->SetFrame(extent);
  397.             fShapeView->InvalShape(shape);
  398.         }
  399.         shape->SetWasSelected(shape->IsSelected());
  400.     }
  401. }
  402.  
  403. //----------------------------------------------------------------------------------------
  404. // TShapeDragger::RedoIt
  405. //----------------------------------------------------------------------------------------
  406. #pragma segment ADoCommand
  407.  
  408. void TShapeDragger::RedoIt()    // Override
  409. {
  410.     fShapeView->RestoreSelection();
  411.  
  412.     this->MoveBy(fDeltaH, fDeltaV);
  413. }
  414.  
  415. //----------------------------------------------------------------------------------------
  416. // TShapeDragger::TrackConstrain
  417. //----------------------------------------------------------------------------------------
  418. #pragma segment ADoCommand
  419.  
  420. void TShapeDragger::TrackConstrain(TrackPhase /*aTrackPhase*/,
  421.                                    const VPoint& anchorPoint,
  422.                                    const VPoint& /*previousPoint*/,
  423.                                    VPoint& nextPoint,
  424.                                    Boolean /*mouseDidMove*/)    // Override
  425. {
  426.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  427.     {
  428.         VCoordinate temp = anchorPoint[vhs] - fBounds[topLeft][vhs];
  429.         nextPoint[vhs] = Max(temp, nextPoint[vhs]);
  430.  
  431.         temp = fShapeView->fSize[vhs] - (fBounds[botRight][vhs] - anchorPoint[vhs]);
  432.         nextPoint[vhs] = Min(temp, nextPoint[vhs]);
  433.     }
  434. }
  435.  
  436. //----------------------------------------------------------------------------------------
  437. // TShapeDragger::TrackFeedback
  438. //----------------------------------------------------------------------------------------
  439. #pragma segment ADoCommand
  440.  
  441. void TShapeDragger::TrackFeedback(TrackPhase aTrackPhase,
  442.                                   const VPoint& anchorPoint,
  443.                                   const VPoint& previousPoint,
  444.                                   const VPoint& nextPoint,
  445.                                   Boolean mouseDidMove,
  446.                                   Boolean turnItOn)    // Override
  447. {
  448.     Inherited::TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint,
  449.                              mouseDidMove, turnItOn);
  450.     if (mouseDidMove && fShapeView->IsDragging())
  451.     {
  452.         CPoint delta;
  453.         delta.h = (short) (nextPoint.h - anchorPoint.h);
  454.         delta.v = (short) (nextPoint.v - anchorPoint.v);
  455.  
  456.         CRect aRect(fBounds);
  457.         OffsetRect(aRect, delta.h, delta.v);
  458.  
  459.         FrameRect(aRect);                        // draw/erase it
  460.     }
  461. }
  462.  
  463. //----------------------------------------------------------------------------------------
  464. // TShapeDragger::TrackMouse
  465. //----------------------------------------------------------------------------------------
  466. #pragma segment ADoCommand
  467.  
  468. TTracker* TShapeDragger::TrackMouse(TrackPhase aTrackPhase,
  469.                                     VPoint& anchorPoint,
  470.                                     VPoint& previousPoint,
  471.                                     VPoint& nextPoint,
  472.                                     Boolean mouseDidMove)    // Override
  473. {
  474.     TTracker* newTracker = Inherited::TrackMouse(aTrackPhase, anchorPoint, previousPoint,
  475.                                                  nextPoint, mouseDidMove);
  476.     if (aTrackPhase == trackRelease)
  477.     {
  478.         if (fShapeView->IsDragging())
  479.         {
  480.             fDeltaH = previousPoint.h - anchorPoint.h;
  481.             fDeltaV = previousPoint.v - anchorPoint.v;
  482.             fShapeView->SetDragging(false);
  483.         }
  484.         else
  485.             newTracker = NULL;
  486.     }
  487.     else if (aTrackPhase == trackMove)
  488.     {
  489.         if (mouseDidMove)
  490.             if (!fShapeView->IsDragging())            // this is first move
  491.             {
  492.                 fShapeView->DoHighlightSelection(hlOn, hlOff);
  493.                 fShapeDocument->EachVirtualShapeDo(&EraseShape, (void*)fShapeView);
  494.                 fShapeView->SetDragging(true);
  495.                 fShapeView->GetWindow()->Update();    // ???
  496.                 fShapeView->Focus();                // UpdateEvent changes the focus - restore it
  497.             }
  498.     }
  499.  
  500.     return newTracker;
  501. }
  502.  
  503. //----------------------------------------------------------------------------------------
  504. // TShapeDragger::UndoIt
  505. //----------------------------------------------------------------------------------------
  506. #pragma segment ADoCommand
  507.  
  508. void TShapeDragger::UndoIt()    // Override
  509. {
  510.     fShapeView->RestoreSelection();
  511.  
  512.     this->MoveBy(-fDeltaH, -fDeltaV);
  513. }
  514.  
  515. //========================================================================================
  516. // CLASS TReshadeCmd
  517. //========================================================================================
  518. #undef Inherited
  519. #define Inherited TTearOffMenuViewTracker
  520.  
  521. #pragma segment ASelCommand
  522. MA_DEFINE_CLASS_M1(TReshadeCmd, Inherited);
  523.  
  524. //----------------------------------------------------------------------------------------
  525. // TReshadeCmd Constructor
  526. //----------------------------------------------------------------------------------------
  527. #pragma segment ASelCommand
  528.  
  529. TReshadeCmd::TReshadeCmd()
  530. {
  531.     fShapeView = NULL;
  532.     fShapeDocument = NULL;
  533.     fPattern = 0;
  534.     fExitTracking = false;
  535.     fMenuPatternsPalette = NULL;
  536.     fFloatingPatternsPalette = NULL;
  537. }
  538.  
  539. //----------------------------------------------------------------------------------------
  540. // TReshadeCmd::IReshadeCmd
  541. //----------------------------------------------------------------------------------------
  542. #pragma segment ASelCommand
  543.  
  544. void TReshadeCmd::IReshadeCmd(CommandNumber itsCommandNumber,
  545.                               TShapeView* itsShapeView,
  546.                               TPatternsPalette* thePatternsPalette,
  547.                               TPatternsPalette* menuPatternsPalette,
  548.                               TPatternsPalette* floatingPatternsPalette,
  549.                               const VPoint& theMouse)
  550. // thePatternsPalette is the view we're tracking in
  551. // floatingPatternsPalette is the view that's in the floating window
  552. {
  553.     TDocument* doc = NULL;
  554.     if (itsShapeView)
  555.         doc = itsShapeView->fDocument;
  556.     this->ITearOffMenuViewTracker(cChangeShade, doc, kCanUndo, kCausesChange, doc,
  557.                                   thePatternsPalette, NULL, theMouse);
  558.  
  559.     fShapeView = itsShapeView;
  560.     fShapeDocument = itsShapeView->fShapeDocument;
  561.     fMenuPatternsPalette = menuPatternsPalette;
  562.     fFloatingPatternsPalette = floatingPatternsPalette;
  563.     fPattern = (short) (itsCommandNumber - cPatterns);
  564.     fViewConstrain = false;
  565. }
  566.  
  567. //----------------------------------------------------------------------------------------
  568. // TReshadeCmd::TrackMouse
  569. //----------------------------------------------------------------------------------------
  570. #pragma segment ADoCommand
  571.  
  572. TTracker* TReshadeCmd::TrackMouse(TrackPhase aTrackPhase,
  573.                                   VPoint& /*anchorPoint*/,
  574.                                   VPoint& /*previousPoint*/,
  575.                                   VPoint& nextPoint,
  576.                                   Boolean /*mouseDidMove*/)    // Override
  577. {
  578.     TTracker* newTracker = this;
  579.     if (gTrackingInMenu)
  580.     {
  581.         /* quit tracking when the mouse leaves the view
  582.             - if gTrackingInMenu is TRUE, view constrain is set to FALSE, so nextPoint CAN leave the view
  583.             - all other times, view constrain is TRUE, so nextPoint WON'T leave the view
  584.         */
  585.         if (fView && fView->IsShown())
  586.             fExitTracking = !fView->ContainsMouse(nextPoint);
  587.  
  588.         /* if gTrackingInMenu is TRUE, then fExitTracking might get set to TRUE above, meaning
  589.            that the user is either returning to the menubar or trying to tear off this
  590.            menu, so simply return NULL when we're done tracking and the tracker will be freed
  591.            by TApplication::TrackMouse.
  592.         */
  593.         if ((aTrackPhase == trackRelease) && fExitTracking)
  594.             newTracker = NULL;
  595.     }
  596.  
  597.     return newTracker;
  598. }
  599.  
  600. //----------------------------------------------------------------------------------------
  601. // TReshadeCmd::TrackFeedback
  602. //----------------------------------------------------------------------------------------
  603. #pragma segment ADoCommand
  604.  
  605. void TReshadeCmd::TrackFeedback(TrackPhase aTrackPhase,
  606.                                 const VPoint& anchorPoint,
  607.                                 const VPoint& previousPoint,
  608.                                 const VPoint& nextPoint,
  609.                                 Boolean mouseDidMove,
  610.                                 Boolean turnItOn)    // Override
  611. {
  612.     // All we really want to do here is let the view give us some feedback, so...
  613.     if (fView && fView->IsShown() && mouseDidMove)
  614.         fView->TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint, mouseDidMove, turnItOn);
  615.  
  616.     /* When we're selecting a pattern (i.e. turning it on) then this command needs to know
  617.        about the new selection. When we're deselecting a pattern (i.e. turning it off) then this
  618.        command MUST ignore the deselection since MacApp's tracking will turn off the current 
  619.        selection as part of its default tracking behavior even when the user has made a valid
  620.        selection in the view.
  621.     */
  622.     if (turnItOn)
  623.         fPattern = ((TPatternsPalette*)fView)->fSelectedPattern;
  624. }
  625.  
  626. //----------------------------------------------------------------------------------------
  627. // TReshadeCmd::IsDoneTracking
  628. //----------------------------------------------------------------------------------------
  629. #pragma segment ADoCommand
  630.  
  631. Boolean TReshadeCmd::IsDoneTracking()    // Override
  632. {
  633.     return !StillDown() || fExitTracking;
  634. }
  635.  
  636. //----------------------------------------------------------------------------------------
  637. // TReshadeCmd::DoIt
  638. //----------------------------------------------------------------------------------------
  639. #pragma segment ADoCommand
  640.  
  641. void TReshadeCmd::DoIt()    // Override
  642. {
  643.     // tell the patterns view in the menu which pattern is selected
  644.     if (fMenuPatternsPalette)
  645.     {
  646.         fMenuPatternsPalette->fOldPattern = fMenuPatternsPalette->fCurrPattern;
  647.         fMenuPatternsPalette->fCurrPattern = fPattern;
  648.     }
  649.  
  650.     // tell the floating window which pattern is selected
  651.     if (fFloatingPatternsPalette)
  652.     {
  653.         fFloatingPatternsPalette->fOldPattern = fFloatingPatternsPalette->fCurrPattern;
  654.         fFloatingPatternsPalette->SelectNewPattern(fPattern);
  655.     }
  656.  
  657.     if (fShapeDocument)
  658.     {
  659.         if (fShapeView)
  660.             fShapeView->Focus();
  661.         /* fShapeDocument.EachShapeDo(ReshadeShape); */
  662.         CShapeIterator iter(fShapeDocument->GetShapeList());
  663.         for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  664.         {
  665.             if (shape->IsSelected())
  666.             {
  667.                 shape->ReplacePattern(fPattern);
  668.                 fShapeView->InvalShape(shape);
  669.             }
  670.             shape->SetWasIsSelected();
  671.         }
  672.     }
  673. }
  674.  
  675. //----------------------------------------------------------------------------------------
  676. // TReshadeCmd::RedoIt
  677. //----------------------------------------------------------------------------------------
  678. #pragma segment ADoCommand
  679.  
  680. void TReshadeCmd::RedoIt()    // Override
  681. {
  682.     // tell the floating window which pattern is selected
  683.     if (fFloatingPatternsPalette)
  684.         fFloatingPatternsPalette->SelectNewPattern(fPattern);
  685.  
  686.     if (fShapeView)
  687.     {
  688.         fShapeView->Focus();
  689.         fShapeView->Deselect();
  690.         /* fShapeDocument.EachShapeDo(ReshadeShape); */
  691.         CShapeIterator iter(fShapeDocument->GetShapeList());
  692.         for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  693.         {
  694.             if (shape->WasSelected())
  695.             {
  696.                 shape->ReplacePattern(fPattern);
  697.                 fShapeView->InvalShape(shape);
  698.             }
  699.             shape->SetIsWasSelected();
  700.         }
  701.     }
  702. }
  703.  
  704. //----------------------------------------------------------------------------------------
  705. // TReshadeCmd::UndoIt
  706. //----------------------------------------------------------------------------------------
  707. #pragma segment ADoCommand
  708.  
  709. void TReshadeCmd::UndoIt()    // Override
  710. {
  711.     // tell the floating window which pattern *was* selected
  712.     if (fFloatingPatternsPalette)
  713.         fFloatingPatternsPalette->SelectNewPattern(fFloatingPatternsPalette->fOldPattern);
  714.  
  715.     if (fShapeView)
  716.     {
  717.         fShapeView->Focus();
  718.         fShapeView->Deselect();
  719.         /* fShapeDocument.EachShapeDo(ReshadeShape); */
  720.         CShapeIterator iter(fShapeDocument->GetShapeList());
  721.         for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  722.         {
  723.             if (shape->WasSelected())
  724.             {
  725.                 shape->fPattern = shape->fOldPattern;
  726.                 fShapeView->InvalShape(shape);
  727.             }
  728.             shape->SetIsWasSelected();
  729.         }
  730.     }
  731. }
  732.  
  733. //========================================================================================
  734. // CLASS TRecolorCmd
  735. //========================================================================================
  736. #undef Inherited
  737. #define Inherited TShapeCommand
  738.  
  739. #pragma segment ASelCommand
  740. MA_DEFINE_CLASS_M1(TRecolorCmd, Inherited);
  741.  
  742. //----------------------------------------------------------------------------------------
  743. // TRecolorCmd Constructor
  744. //----------------------------------------------------------------------------------------
  745. #pragma segment ASelCommand
  746.  
  747. TRecolorCmd::TRecolorCmd()
  748. {
  749.     fColor = gRGBBlack;
  750. }
  751.  
  752. //----------------------------------------------------------------------------------------
  753. // TRecolorCmd::IRecolorCmd
  754. //----------------------------------------------------------------------------------------
  755. #pragma segment ASelCommand
  756.  
  757. void TRecolorCmd::IRecolorCmd(CRGBColor itsColor, TShapeView* itsShapeView)
  758. {
  759.     this->IShapeCommand(cChangeColor, itsShapeView, kCanUndo, kCausesChange,
  760.                         gZeroVPt, !kBetterFeedbackDesired);
  761.     fColor = itsColor;
  762. }
  763.  
  764. //----------------------------------------------------------------------------------------
  765. // TRecolorCmd::DoIt
  766. //----------------------------------------------------------------------------------------
  767. #pragma segment ADoCommand
  768.  
  769. void TRecolorCmd::DoIt()    // Override
  770. {
  771.     fShapeView->Focus();
  772.  
  773.     /* fShapeDocument.EachShapeDo(RecolorShape); */
  774.     CShapeIterator iter(fShapeDocument->GetShapeList());
  775.     for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  776.     {
  777.         if (shape->IsSelected())
  778.         {
  779.             shape->ReplaceColor(fColor);
  780.             fShapeView->InvalShape(shape);
  781.         }
  782.         shape->SetWasIsSelected();
  783.     }
  784. }
  785.  
  786. //----------------------------------------------------------------------------------------
  787. // TRecolorCmd::RedoIt
  788. //----------------------------------------------------------------------------------------
  789. #pragma segment ADoCommand
  790.  
  791. void TRecolorCmd::RedoIt()    // Override
  792. {
  793.     fShapeView->Focus();
  794.     fShapeView->Deselect();
  795.  
  796.     /* fShapeDocument.EachShapeDo(RecolorShape); */
  797.     CShapeIterator iter(fShapeDocument->GetShapeList());
  798.     for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  799.     {
  800.         if (shape->WasSelected())
  801.         {
  802.             shape->ReplaceColor(fColor);
  803.             fShapeView->InvalShape(shape);
  804.         }
  805.         shape->SetIsWasSelected();
  806.     }
  807. }
  808.  
  809. //----------------------------------------------------------------------------------------
  810. // TRecolorCmd::UndoIt
  811. //----------------------------------------------------------------------------------------
  812. #pragma segment ADoCommand
  813.  
  814. void TRecolorCmd::UndoIt()    // Override
  815. {
  816.     fShapeView->Focus();
  817.     fShapeView->Deselect();
  818.  
  819.     /* fShapeDocument.EachShapeDo(RecolorShape); */
  820.     CShapeIterator iter(fShapeDocument->GetShapeList());
  821.     for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  822.     {
  823.         if (shape->WasSelected())
  824.         {
  825.             shape->fColor = shape->fOldColor;
  826.             fShapeView->InvalShape(shape);
  827.         }
  828.         shape->SetIsWasSelected();
  829.     }
  830. }
  831.  
  832. //========================================================================================
  833. // CLASS TShapeReplaceCommand
  834. //========================================================================================
  835. #undef Inherited
  836. #define Inherited TShapeCommand
  837.  
  838. #pragma segment ASelCommand
  839. MA_DEFINE_CLASS_M1(TShapeReplaceCommand, Inherited);
  840.  
  841. //----------------------------------------------------------------------------------------
  842. // TShapeReplaceCommand Constructor
  843. //----------------------------------------------------------------------------------------
  844. #pragma segment ASelCommand
  845.  
  846. TShapeReplaceCommand::TShapeReplaceCommand()
  847. {
  848. }
  849.  
  850. //----------------------------------------------------------------------------------------
  851. // TShapeReplaceCommand::IShapeReplaceCommand
  852. //----------------------------------------------------------------------------------------
  853. #pragma segment ASelCommand
  854.  
  855. void TShapeReplaceCommand::IShapeReplaceCommand(CommandNumber itsCommandNumber,
  856.                                                 TShapeView* itsShapeView,
  857.                                                 const VPoint& theMouse,
  858.                                                 Boolean betterFeedbackDesired)
  859. {
  860.     this->IShapeCommand(itsCommandNumber, itsShapeView,
  861.                         kCanUndo, kCausesChange,
  862.                         theMouse, betterFeedbackDesired);
  863. }
  864.  
  865. //----------------------------------------------------------------------------------------
  866. // TShapeReplaceCommand::Commit
  867. //----------------------------------------------------------------------------------------
  868. #pragma segment ADoCommand
  869.  
  870. void TShapeReplaceCommand::Commit()    // Override
  871. {
  872.     if (fShapeDocument->IsFiltering())
  873.     {
  874.         fShapeDocument->EachShapeDo(&HandleIt, (void*)fShapeDocument);
  875.     }
  876.     fShapeDocument->SetFiltering(false);
  877.     fShapeDocument->fReplaceCommand = NULL;
  878. }
  879.  
  880. //----------------------------------------------------------------------------------------
  881. // TShapeReplaceCommand::RedoIt
  882. //----------------------------------------------------------------------------------------
  883. #pragma segment ADoCommand
  884.  
  885. void TShapeReplaceCommand::RedoIt()    // Override
  886. {
  887.     if (fShapeDocument->IsFiltering())
  888.         fShapeView->RestoreSelection();
  889.     fShapeDocument->fReplaceCommand = this;
  890. }
  891.  
  892. //----------------------------------------------------------------------------------------
  893. // TShapeReplaceCommand::UndoIt
  894. //----------------------------------------------------------------------------------------
  895. #pragma segment ADoCommand
  896.  
  897. void TShapeReplaceCommand::UndoIt()    // Override
  898. {
  899.     fShapeView->RestoreSelection();
  900.     fShapeDocument->fReplaceCommand = NULL;
  901.     fShapeDocument->SetFiltering(false);
  902. }
  903.  
  904. //----------------------------------------------------------------------------------------
  905. // TShapeReplaceCommand::EachNewShapeDo
  906. //----------------------------------------------------------------------------------------
  907. #pragma segment ADoCommand
  908.  
  909. void TShapeReplaceCommand::EachNewShapeDo(DoToShapeType /*DoToShape*/, void* /*staticLink*/)
  910. {
  911.     // Do nothing
  912. }
  913.  
  914. //========================================================================================
  915. // CLASS TShapeSketcher
  916. //========================================================================================
  917. #undef Inherited
  918. #define Inherited TShapeReplaceCommand
  919.  
  920. #pragma segment ASelCommand
  921. MA_DEFINE_CLASS_M1(TShapeSketcher, Inherited);
  922.  
  923. //----------------------------------------------------------------------------------------
  924. // TShapeSketcher Constructor
  925. //----------------------------------------------------------------------------------------
  926. #pragma segment ASelCommand
  927.  
  928. TShapeSketcher::TShapeSketcher()
  929. {
  930.     fShape = NULL;
  931. }
  932.  
  933. //----------------------------------------------------------------------------------------
  934. // TShapeSketcher::IShapeSketcher
  935. //----------------------------------------------------------------------------------------
  936. #pragma segment ASelCommand
  937.  
  938. void TShapeSketcher::IShapeSketcher(TShapeView* itsShapeView,
  939.                                     TShape* protoShape,
  940.                                     const VPoint& theMouse,
  941.                                     Boolean constrain)
  942. {
  943.     this->IShapeReplaceCommand(cNewShape, itsShapeView,
  944.                                theMouse, gBetterFeedback);
  945.     fShape = protoShape;
  946.     fConstrainsMouse = constrain;
  947. }
  948.  
  949. //----------------------------------------------------------------------------------------
  950. // TShapeSketcher::Free
  951. //----------------------------------------------------------------------------------------
  952. #pragma segment ADoCommand
  953.  
  954. void TShapeSketcher::Free()    // Override
  955. {
  956.     fShape = (TShape*)FreeIfObject(fShape);
  957.     Inherited::Free();
  958. }
  959.  
  960. //----------------------------------------------------------------------------------------
  961. // TShapeSketcher::DoIt
  962. //----------------------------------------------------------------------------------------
  963. #pragma segment ADoCommand
  964.  
  965. void TShapeSketcher::DoIt()    // Override
  966. {
  967.     fShape->SetSelected(true);
  968.     
  969.     fShape->DoInitialState(fShapeView);
  970.  
  971.     fShapeDocument->fReplaceCommand = this;
  972.     fShapeView->InvalShape(fShape);
  973. }
  974.  
  975. //----------------------------------------------------------------------------------------
  976. // TShapeSketcher::UndoIt
  977. //----------------------------------------------------------------------------------------
  978. #pragma segment ADoCommand
  979.  
  980. void TShapeSketcher::UndoIt()    // Override
  981. {
  982.     Inherited::UndoIt();
  983.     fShapeView->InvalShape(fShape);
  984. }
  985.  
  986. //----------------------------------------------------------------------------------------
  987. // TShapeSketcher::RedoIt
  988. //----------------------------------------------------------------------------------------
  989. #pragma segment ADoCommand
  990.  
  991. void TShapeSketcher::RedoIt()    // Override
  992. {
  993.     fShapeView->Focus();
  994.     fShapeView->Deselect();
  995.     Inherited::RedoIt();
  996.     fShape->SetSelected(true);
  997.     fShapeView->InvalShape(fShape);
  998. }
  999.  
  1000. //----------------------------------------------------------------------------------------
  1001. // TShapeSketcher::Commit
  1002. //----------------------------------------------------------------------------------------
  1003. #pragma segment ADoCommand
  1004.  
  1005. void TShapeSketcher::Commit()    // Override
  1006. {
  1007.     /* As a rule - Commit methods should not be allowed to Fail.  This commit method is a bad
  1008.        example in that a new shape is added to the document - this could actually cause this
  1009.        Commit method to Fail.
  1010.     */
  1011.  
  1012.     fShapeDocument->AddShape(fShape);            // Add the shape to the list
  1013.     // Set this field to NULL to prevent Free from freeing it
  1014.     fShape = NULL;
  1015.     Inherited::Commit();
  1016. }
  1017.  
  1018. //----------------------------------------------------------------------------------------
  1019. // TShapeSketcher::EachNewShapeDo
  1020. //----------------------------------------------------------------------------------------
  1021. #pragma segment ADoCommand
  1022.  
  1023. void TShapeSketcher::EachNewShapeDo(DoToShapeType DoToShape, void* staticLink)    // Override
  1024. {
  1025.     DoToShape(fShape, staticLink);
  1026. }
  1027.  
  1028. //----------------------------------------------------------------------------------------
  1029. // TShapeSketcher::TrackConstrain
  1030. //----------------------------------------------------------------------------------------
  1031. #pragma segment ADoCommand
  1032.  
  1033. void TShapeSketcher::TrackConstrain(TrackPhase /*aTrackPhase*/,
  1034.                                     const VPoint& anchorPoint,
  1035.                                     const VPoint& /*previousPoint*/,
  1036.                                     VPoint& nextPoint,
  1037.                                     Boolean /*mouseDidMove*/)    // Override
  1038. {
  1039.     long dh, dv, absDh, absDv, delta;
  1040.  
  1041.     dh = nextPoint.h - anchorPoint.h;
  1042.     dv = nextPoint.v - anchorPoint.v;
  1043.     absDh = abs((int)dh);
  1044.     absDv = abs((int)dv);
  1045.     delta = Min(absDh, absDv);
  1046.  
  1047.     if (dh < 0)
  1048.         dh = - delta;
  1049.     else
  1050.         dh = delta;
  1051.     if (dv < 0)
  1052.         dv = - delta;
  1053.     else
  1054.         dv = delta;
  1055.  
  1056.     nextPoint.h = anchorPoint.h + dh;
  1057.     nextPoint.v = anchorPoint.v + dv;
  1058. }
  1059.  
  1060. //----------------------------------------------------------------------------------------
  1061. // TShapeSketcher::TrackFeedback
  1062. //----------------------------------------------------------------------------------------
  1063. #pragma segment ADoCommand
  1064.  
  1065. void TShapeSketcher::TrackFeedback(TrackPhase aTrackPhase,
  1066.                                    const VPoint& anchorPoint,
  1067.                                    const VPoint& previousPoint,
  1068.                                    const VPoint& nextPoint,
  1069.                                    Boolean mouseDidMove,
  1070.                                    Boolean turnItOn)    // Override
  1071. {
  1072.     Inherited::TrackFeedback(aTrackPhase, anchorPoint, previousPoint, nextPoint,
  1073.                              mouseDidMove, turnItOn);
  1074.     if (mouseDidMove && fShape)
  1075.         fShape->DrawOutline();
  1076. }
  1077.  
  1078. //----------------------------------------------------------------------------------------
  1079. // TShapeSketcher::TrackMouse
  1080. //----------------------------------------------------------------------------------------
  1081. #pragma segment ADoCommand
  1082.  
  1083. TTracker* TShapeSketcher::TrackMouse(TrackPhase aTrackPhase,
  1084.                                      VPoint& anchorPoint,
  1085.                                      VPoint& previousPoint,
  1086.                                      VPoint& nextPoint,
  1087.                                      Boolean mouseDidMove)    // Override
  1088. {
  1089.     TTracker* newTracker = Inherited::TrackMouse(aTrackPhase, anchorPoint, previousPoint,
  1090.                                                  nextPoint, mouseDidMove);
  1091.  
  1092.     if (aTrackPhase == trackRelease)        // create the new shape
  1093.     {
  1094.         Boolean bigEnough = false;
  1095.  
  1096.         VPoint size;
  1097.         size.h = nextPoint.h - anchorPoint.h;
  1098.         size.v = nextPoint.v - anchorPoint.v;
  1099.         if (abs((int)size.h) >= kMinWidth)
  1100.             if (abs((int)size.v) >= kMinHeight)
  1101.                 bigEnough = true;
  1102.  
  1103.         if (!bigEnough)
  1104.         {
  1105.             fShape = (TShape*)FreeIfObject(fShape);
  1106.             newTracker = NULL;
  1107.         }
  1108.     }
  1109.     else
  1110.     {
  1111.         VRect aVRect;
  1112.         CRect r;
  1113.         Pt2VRect(anchorPoint, nextPoint, aVRect);
  1114.         VRectToRect(aVRect, r);                // OK because we know the view's size is in QD dimensions
  1115.         fShape->SetFrame(r);
  1116.     }
  1117.  
  1118.     return newTracker;
  1119. }
  1120.  
  1121. //========================================================================================
  1122. // CLASS TShapeCutCopyCommand
  1123. //========================================================================================
  1124. #undef Inherited
  1125. #define Inherited TShapeReplaceCommand
  1126.  
  1127. #pragma segment ASelCommand
  1128. MA_DEFINE_CLASS_M1(TShapeCutCopyCommand, Inherited);
  1129.  
  1130. //----------------------------------------------------------------------------------------
  1131. // TShapeCutCopyCommand Constructor
  1132. //----------------------------------------------------------------------------------------
  1133. #pragma segment ASelCommand
  1134.  
  1135. TShapeCutCopyCommand::TShapeCutCopyCommand()
  1136. {
  1137. }
  1138.  
  1139. //----------------------------------------------------------------------------------------
  1140. // TShapeCutCopyCommand::IShapeCutCopyCommand
  1141. //----------------------------------------------------------------------------------------
  1142. #pragma segment ASelCommand
  1143.  
  1144. void TShapeCutCopyCommand::IShapeCutCopyCommand(CommandNumber itsCommandNumber,
  1145.                                                 TShapeView* itsShapeView)
  1146. {
  1147.     this->IShapeReplaceCommand(itsCommandNumber, itsShapeView, gZeroVPt, !kBetterFeedbackDesired);
  1148.     fChangesClipboard = true;
  1149.     fCausesChange = (itsCommandNumber == cCut);
  1150. }
  1151.  
  1152. //----------------------------------------------------------------------------------------
  1153. // TShapeCutCopyCommand::DoIt
  1154. //----------------------------------------------------------------------------------------
  1155. #pragma segment ADoCommand
  1156.  
  1157. void TShapeCutCopyCommand::DoIt()    // Override
  1158. {
  1159.     TShapeView*        clipShapeView;
  1160.     MAVolatileInit(TShapeDocument*, clipDoc, NULL);
  1161.  
  1162.     fShapeView->SaveSelection(fIdentifier == cCut);    // don't invalidate if it's just COPY
  1163.     clipDoc = new TShapeDocument;
  1164.     clipDoc->IShapeDocument(NULL);
  1165.  
  1166.     FailInfo fi;
  1167.  
  1168.     Try(fi)
  1169.     {
  1170.         short count;
  1171.         CRect outline;
  1172.         fShapeDocument->SurveyShapes(true, count, outline);
  1173.  
  1174.         clipShapeView = new TShapeView;
  1175.         clipShapeView->IShapeView(clipDoc, true);
  1176.  
  1177.         // Set fShapeView since the doc will NOT be told to DoMakeViews
  1178.         clipDoc->fShapeView = clipShapeView;
  1179.  
  1180.         if (fIdentifier == cCut)
  1181.             fShapeView->Focus();
  1182.  
  1183.         /* fShapeDocument.EachShapeDo(CopyToClip); */
  1184.         {
  1185.             CShapeIterator iter(fShapeDocument->GetShapeList());
  1186.             for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  1187.                 if (shape->IsSelected())
  1188.                 {
  1189.                     TShape* aNewShape = (TShape*)shape->Clone();
  1190.                     aNewShape->SetSelected(false);
  1191.                     aNewShape->SetWasSelected(false);
  1192.                     CRect r;
  1193.                     shape->GetFrame(r);
  1194.                     OffsetRect(r, gClipMargin.h - outline.left, gClipMargin.v - outline.top);
  1195.                     aNewShape->SetFrame(r);
  1196.     
  1197.                     clipDoc->AddShape(aNewShape);
  1198.                 }
  1199.         }
  1200.         clipShapeView->AdjustFrame();
  1201.  
  1202.         // Make sure the Cut left us with enough memory to continue.
  1203.         FailSpaceIsLow();
  1204.         fi.Success();
  1205.     }
  1206.     else
  1207.     {
  1208.         FreeIfObject(clipDoc);
  1209.         fi.ReSignal();
  1210.     }
  1211.  
  1212.     this->ClaimClipboard(clipShapeView);
  1213.     fShapeDocument->SetFiltering(fIdentifier != cCopy);
  1214.     fShapeDocument->fReplaceCommand = this;
  1215. }
  1216.  
  1217. void TShapeCutCopyCommand::RedoIt()    // Override
  1218. {
  1219.     fShapeDocument->SetFiltering(fIdentifier != cCopy);
  1220.     Inherited::RedoIt();
  1221. }
  1222.  
  1223. //========================================================================================
  1224. // CLASS TShapeClearCommand
  1225. //========================================================================================
  1226. #undef Inherited
  1227. #define Inherited TShapeReplaceCommand
  1228.  
  1229. #pragma segment ASelCommand
  1230. MA_DEFINE_CLASS_M1(TShapeClearCommand, Inherited);
  1231.  
  1232. //----------------------------------------------------------------------------------------
  1233. // TShapeClearCommand Constructor
  1234. //----------------------------------------------------------------------------------------
  1235. #pragma segment ASelCommand
  1236.  
  1237. TShapeClearCommand::TShapeClearCommand()
  1238. {
  1239. }
  1240.  
  1241. //----------------------------------------------------------------------------------------
  1242. // TShapeClearCommand::IShapeClearCommand
  1243. //----------------------------------------------------------------------------------------
  1244. #pragma segment ASelCommand
  1245.  
  1246. void TShapeClearCommand::IShapeClearCommand(TShapeView* itsShapeView)
  1247. {
  1248.     this->IShapeReplaceCommand(cClear, itsShapeView, gZeroVPt, !kBetterFeedbackDesired);
  1249. }
  1250.  
  1251. //----------------------------------------------------------------------------------------
  1252. // TShapeClearCommand::DoIt
  1253. //----------------------------------------------------------------------------------------
  1254. #pragma segment ADoCommand
  1255.  
  1256. void TShapeClearCommand::DoIt()    // Override
  1257. {
  1258.     fShapeView->SaveSelection(true);    // TRUE means invalidate the shapes
  1259.     fShapeDocument->SetFiltering(true);
  1260.     fShapeDocument->fReplaceCommand = this;
  1261. }
  1262.  
  1263. //----------------------------------------------------------------------------------------
  1264. // TShapeClearCommand::RedoIt
  1265. //----------------------------------------------------------------------------------------
  1266. #pragma segment ADoCommand
  1267.  
  1268. void TShapeClearCommand::RedoIt()    // Override
  1269. {
  1270.     fShapeDocument->SetFiltering(true);
  1271.     Inherited::RedoIt();
  1272. }
  1273.  
  1274. //========================================================================================
  1275. // CLASS TShapePasteCommand
  1276. //========================================================================================
  1277. #undef Inherited
  1278. #define Inherited TShapeReplaceCommand
  1279.  
  1280. #pragma segment ASelCommand
  1281. MA_DEFINE_CLASS_M1(TShapePasteCommand, Inherited);
  1282.  
  1283. //----------------------------------------------------------------------------------------
  1284. // TShapePasteCommand Constructor
  1285. //----------------------------------------------------------------------------------------
  1286. #pragma segment ASelCommand
  1287.  
  1288. TShapePasteCommand::TShapePasteCommand()
  1289. {
  1290.     fPasteList = NULL;
  1291. }
  1292.  
  1293. //----------------------------------------------------------------------------------------
  1294. // TShapePasteCommand::IShapePasteCommand
  1295. //----------------------------------------------------------------------------------------
  1296. #pragma segment ASelCommand
  1297.  
  1298. void TShapePasteCommand::IShapePasteCommand(TShapeView* itsShapeView)
  1299. {
  1300.     this->IShapeReplaceCommand(cPaste, itsShapeView, gZeroVPt, !kBetterFeedbackDesired);
  1301.  
  1302.     FailInfo fi;
  1303.     Try(fi)
  1304.     {
  1305.         fPasteList = new TShapeList;
  1306.         fPasteList->IList();
  1307. #if qDebug
  1308.         fPasteList->SetEltType("TShape");
  1309. #endif
  1310.         fi.Success();
  1311.     }
  1312.     else
  1313.     {
  1314.         this->Free();
  1315.         fi.ReSignal();
  1316.     }
  1317. }
  1318.  
  1319. //----------------------------------------------------------------------------------------
  1320. // TShapePasteCommand::Free
  1321. //----------------------------------------------------------------------------------------
  1322. #pragma segment ADoCommand
  1323.  
  1324. void TShapePasteCommand::Free()    // Override
  1325. {
  1326.     fPasteList = (TShapeList*)FreeIfObject(fPasteList);
  1327.  
  1328.     Inherited::Free();
  1329. }
  1330.  
  1331. //----------------------------------------------------------------------------------------
  1332. // TShapePasteCommand::Commit
  1333. //----------------------------------------------------------------------------------------
  1334. #pragma segment ADoCommand
  1335.  
  1336. void TShapePasteCommand::Commit()    // Override
  1337. {
  1338.     if (gPasteReplacesSelection)
  1339.         Inherited::Commit();                // Deletes old selectees from the document
  1340.  
  1341.     /* The following loop transfers shapes from fPasteList to the document's
  1342.        shape list, in such a way that fPasteList is shrunk while the 
  1343.        document's shape list is grown. This helps prevent running out
  1344.        of memory when Commiting a Paste command.
  1345.     */
  1346.  
  1347.     //    As a rule - Commit methods should not be allowed to fail. This Commit method is a
  1348.     //    bad example in that a new shape is added to the document - this could actually cause
  1349.     //    this Commit method to fail.
  1350.  
  1351.     TShape* theShape = (TShape*)fPasteList->First();
  1352.     while (theShape)
  1353.     {
  1354.         fPasteList->Delete(theShape);
  1355.         fShapeDocument->AddShape(theShape);
  1356.         theShape = (TShape*)fPasteList->First();
  1357.     }
  1358.  
  1359.     fShapeDocument->fReplaceCommand = NULL;
  1360. }
  1361.  
  1362. //----------------------------------------------------------------------------------------
  1363. // TShapePasteCommand::DoIt
  1364. //----------------------------------------------------------------------------------------
  1365. #pragma segment ADoCommand
  1366.  
  1367. void TShapePasteCommand::DoIt()    // Override
  1368. {
  1369.     CPoint    whereToPaste;
  1370.     TView* clipView = gClipboardMgr->fClipView;
  1371.     FailNonObject(clipView);
  1372.  
  1373. #if qDebug
  1374.     if (!clipView->DescendsFrom(TShapeView::GetClassDescStatic()))
  1375.         ProgramBreak("Attempt to paste a non-TShapeView clipboard");
  1376. #endif
  1377.     // The next section figures out where the pasted shapes should be placed in the view.
  1378.     // Lovely, isn't it?
  1379.     if (gPasteReplacesSelection)
  1380.     {
  1381.         // If we're replacing shapes, then paste the new shapes starting at the top-left
  1382.         // corner of the replaced shapes. Otherwise, start at the last clicked point in
  1383.         // the view.
  1384.         short noOfShapes;
  1385.         CRect extent;
  1386.         fShapeDocument->SurveyShapes(true, noOfShapes, extent);
  1387.         if (noOfShapes > 0)
  1388.             whereToPaste = extent[topLeft];
  1389.         else
  1390.             whereToPaste = fShapeView->fClickPt;
  1391.     }
  1392.     else
  1393.     {
  1394.         VRect scrollerExtent;
  1395.         fShapeView->fSuperView->GetExtent(scrollerExtent);
  1396.         for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  1397.         {
  1398.             long t;    // temp var
  1399.             t = (scrollerExtent[botRight][vhs] + scrollerExtent[topLeft][vhs] -
  1400.                  clipView->fSize[vhs]) / 2;
  1401.             whereToPaste[vhs] = (short)Max(scrollerExtent[topLeft][vhs], t);
  1402.         }
  1403.     }
  1404.     SubPt(gClipMargin, whereToPaste);
  1405.  
  1406.     fShapeView->SaveSelection(gPasteReplacesSelection);
  1407.     fShapeView->Deselect();
  1408.  
  1409.     if (clipView->GivePasteData(NULL, kShapeClipType) > 0)
  1410.         PasteShapes(whereToPaste);
  1411.     else if (clipView->GivePasteData(NULL, 'PICT') > 0)
  1412.         PastePict(whereToPaste);
  1413.     else if (clipView->GivePasteData(NULL, 'TEXT') > 0)
  1414.         PasteText(whereToPaste);
  1415.  
  1416.     fShapeDocument->SetFiltering(gPasteReplacesSelection);
  1417.     fShapeDocument->fReplaceCommand = this;
  1418.     fShapeView->AdjustFrame();                // Make sure all the Pasted shapes can be seen
  1419. }
  1420.  
  1421. //----------------------------------------------------------------------------------------
  1422. // TShapePasteCommand::UndoIt
  1423. //----------------------------------------------------------------------------------------
  1424. #pragma segment ADoCommand
  1425.  
  1426. void TShapePasteCommand::UndoIt()    // Override
  1427. {
  1428.     Inherited::UndoIt();
  1429.  
  1430.     this->EachNewShapeDo(&BeInvalidated, (void*)fShapeView);
  1431.     fShapeView->Focus();
  1432.     fShapeDocument->SetFiltering(false);
  1433.     fShapeView->AdjustFrame();
  1434. }
  1435.  
  1436. //----------------------------------------------------------------------------------------
  1437. // TShapePasteCommand::RedoIt
  1438. //----------------------------------------------------------------------------------------
  1439. #pragma segment ADoCommand
  1440.  
  1441. void TShapePasteCommand::RedoIt()    // Override
  1442. {
  1443.     fShapeView->Focus();
  1444.     fShapeView->Deselect();
  1445.  
  1446.     // Invalidate all the newly-added shapes
  1447.     this->EachNewShapeDo(&BeSelected, (void*)fShapeView);
  1448.  
  1449.     fShapeDocument->SetFiltering(gPasteReplacesSelection);
  1450.     Inherited::RedoIt();
  1451.     fShapeView->AdjustFrame();                // Make sure size reflects the Paste
  1452. }
  1453.  
  1454. //----------------------------------------------------------------------------------------
  1455. // TShapePasteCommand::EachNewShapeDo
  1456. //----------------------------------------------------------------------------------------
  1457. #pragma segment ADoCommand
  1458.  
  1459. void TShapePasteCommand::EachNewShapeDo(DoToShapeType DoToShape, void* staticLink)    // Override
  1460. {
  1461.     CShapeIterator iter(fPasteList);
  1462.     for (TShape* shape = iter.FirstShape(); iter.More(); shape = iter.NextShape())
  1463.     {
  1464.         DoToShape(shape, staticLink);
  1465.     }
  1466. }
  1467.  
  1468. //----------------------------------------------------------------------------------------
  1469. // TShapePasteCommand::PasteShapes
  1470. //----------------------------------------------------------------------------------------
  1471. #pragma segment ADoCommand
  1472.  
  1473. void TShapePasteCommand::PasteShapes(CPoint whereToPaste)
  1474. {
  1475. #if qDebug
  1476.     if (!gClipboardMgr->fClipView->DescendsFrom(TShapeView::GetClassDescStatic()))
  1477.         ProgramBreak("Attempt to paste a non-TShapeView clipboard");
  1478. #endif
  1479.  
  1480.     TShapeDocument* clipDoc = ((TShapeView*)gClipboardMgr->fClipView)->fShapeDocument;
  1481.     /* clipDoc.EachShapeDo(PasteShape); */
  1482.     CShapeIterator iter(clipDoc->GetShapeList());
  1483.     for (TShape* clipShape = iter.FirstShape(); iter.More(); clipShape = iter.NextShape())
  1484.     {
  1485.         TShape* aShape = (TShape*)clipShape->Clone();
  1486.         aShape->SetSelected(true);
  1487.         aShape->SetWasSelected(true);
  1488.         CRect extent;
  1489.         aShape->GetFrame(extent);
  1490.         OffsetRect(extent, whereToPaste.h, whereToPaste.v);
  1491.         aShape->SetFrame(extent);
  1492.         fPasteList->InsertLast(aShape);
  1493.         aShape->BeInView(fShapeView);
  1494.         fShapeView->InvalShape(aShape);
  1495.     }
  1496. }
  1497.  
  1498. //----------------------------------------------------------------------------------------
  1499. // TShapePasteCommand::PastePict
  1500. //----------------------------------------------------------------------------------------
  1501. #pragma segment ADoCommand
  1502.  
  1503. void TShapePasteCommand::PastePict(CPoint whereToPaste)
  1504. {
  1505.     MAVolatileInit(PicHandle, picture, NULL);
  1506.     FailInfo fi;
  1507.     Try(fi)
  1508.     {
  1509.         picture = (PicHandle)NewPermHandle(0);
  1510.         FailSpaceIsLow();
  1511.  
  1512.         long result = gClipboardMgr->fClipView->GivePasteData((Handle)picture, 'PICT');
  1513.         if (result < 0) FailOSErr((OSErr)result);
  1514.  
  1515.         // Read the shapes from the clipboard and add them to the document
  1516.         CRect extent((**picture).picFrame);
  1517.         OffsetRect(extent, whereToPaste.h, whereToPaste.v);
  1518.         TPictShape* pictShape = new TPictShape;
  1519.         pictShape->IPictShape(extent, 5);
  1520.         ////pictShape->DoInitialState(this);
  1521.         pictShape->SetPicture(picture);
  1522.         pictShape->BeInView(fShapeView);
  1523.         fPasteList->InsertLast(pictShape);
  1524.         fShapeView->InvalShape(pictShape);
  1525.         fi.Success();
  1526.     }
  1527.     else // Recover
  1528.     {
  1529.         DisposeIfHandle((Handle)picture);
  1530.         fi.ReSignal();
  1531.     }
  1532. }
  1533.  
  1534. //----------------------------------------------------------------------------------------
  1535. // TShapePasteCommand::PasteText
  1536. //----------------------------------------------------------------------------------------
  1537. #pragma segment ADoCommand
  1538.  
  1539. void TShapePasteCommand::PasteText(CPoint whereToPaste)
  1540. {
  1541.     MAVolatileInit(Handle, text, NULL);
  1542.     FailInfo fi;
  1543.     Try(fi)
  1544.     {
  1545.         text = NewPermHandle(0);
  1546.         FailSpaceIsLow();
  1547.  
  1548.         long result = gClipboardMgr->fClipView->GivePasteData(text, 'TEXT');
  1549.         if (result < 0) FailOSErr((OSErr)result);
  1550.  
  1551.         // Read the shapes from the clipboard and add them to the document
  1552.         CRect extent(20, 20, 180, 180);
  1553.         OffsetRect(extent, whereToPaste.h, whereToPaste.v);
  1554.         TTextShape* textShape = new TTextShape;
  1555.         textShape->ITextShape(extent, 4);
  1556.         ////textShape->DoInitialState(this);
  1557.         textShape->SetText(text);
  1558.         textShape->BeInView(fShapeView);
  1559.         fPasteList->InsertLast(textShape);
  1560.         fShapeView->InvalShape(textShape);
  1561.         fi.Success();
  1562.     }
  1563.     else // Recover
  1564.     {
  1565.         DisposeIfHandle(text);
  1566.         fi.ReSignal();
  1567.     }
  1568.     DisposeIfHandle(text);
  1569. }
  1570.  
  1571.